/**
 * 
 */
package com.seteam.collabcrossword;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;

/**
 * The main class from where the server execution starts. Here the server
 * creates a thread for each incoming client.
 * 
 * @author SE Team
 * 
 */
public class Core {

	private static final Logger logger = LoggerFactory.getLogger(Core.class);

	/**
	 * Main class starting the server.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		boolean listening = true;
		// Variables to find the count of clients connected to play.
		int count = 0;
		int id = 1;
		// Single message Parser instance, for both the clients joining to play
		// the same game.
		Resources resources = null;
		// Queues needed make the inter client and intra client communication
		// possible.
		SynchronizedQueue<Object> queue = null;
		InterClientQueue<Object> interClientQueueClient1 = null;
		InterClientQueue<Object> interClientQueueClient2 = null;

		try {
			// Create the Server socket which will be listening to
			// the client request.
			serverSocket = new ServerSocket(9999, 10,
					InetAddress.getLocalHost());
			logger.info("Server opened on socket: {}",
					serverSocket.getLocalSocketAddress());
		} catch (IOException e) {
			logger.error("Exception {}", e.getMessage());
		}

		try {

			// The server creates multiple threads for each incoming request.
			// Waits infinitely for all incoming requests.
			while (listening) {

				if (count == 0) {
					resources = new Resources();
					// Queue for inter client communication
					interClientQueueClient1 = new InterClientQueue<Object>();
					interClientQueueClient2 = new InterClientQueue<Object>();

				}
				// Every time a client is created, a new instance of
				// intra-client queue is created and given to the Client thread
				// handler.
				queue = new SynchronizedQueue<Object>();
				logger.info("Waiting for a player");
				// A new client handler for each client is created.
				ClientHandler clientHandler = null;
				// The value of count decides if it is the first client or the
				// second client connecting to the server, in a pair of clients
				if (count == 0) {
					//If value of count is 0, the first client is connecting
					clientHandler = new ClientHandler(serverSocket.accept(),
							id, resources, queue, interClientQueueClient1,
							interClientQueueClient2);

				} else {
					//If the value of the client is 1, second client is connecting.
					clientHandler = new ClientHandler(serverSocket.accept(),
							id, resources, queue, interClientQueueClient2,
							interClientQueueClient1);
				}

				logger.info("Starting handler for client {}", count);
				//Starts the client thread.
				clientHandler.start();

				clientHandler.join();

				// Increase the count each time, to allow only two threads to
				// connect with one unique Id
				count++;
				// When two threads have joined, initialise the count to
				// 0 to indicate two clients have joined.
				if (count == 2) {
					count = 0;
					//Increment the id to  
					id = id + 1;
				}

			}

			// Close the server socket
			serverSocket.close();

		} catch (Exception e) {
			logger.error("Exception {}", e.getMessage());
		}
	}

}
